package parser

import (
	"parse/src/constants"
	"parse/src/interpreter"
	"parse/src/nodes"
	"parse/src/token"
	"parse/src/utils"
)

/*******************************以下是开始进行解析代码，将代码解析成为语法树*********************************/
// 对应语法文件 grammar.txt 里面的statements
// statements  : NEWLINE* statement (NEWLINE+ statement)* NEWLINE*
func (p *Parser) Statements() *ParseResult {
	// 实例化解析结果
	res := NewParseResult()
	posStart := p.CurrentTok.PosStart.Copy()

	// 表示为新行
	for p.CurrentTok.Type_ == constants.TT_NEWLINE {
		res.RegisterAdvancement()
		p.Advance()
	}

	// 注册 statement
	statement := res.Register(p.Statement())

	if statement == nil {
		return res
	}
	if res.Error_ != nil {
		return res
	}

	// 定义一个数组
	var statements []interface{}
	statements = append(statements, statement)

	moreStatement := true
	for { // 循环
		newlineCount := 0
		// 循环拿到当前的token的类型是什么
		for p.CurrentTok.Type_ == constants.TT_NEWLINE {
			res.RegisterAdvancement()
			p.Advance()
			newlineCount++
		}
		// 新行数为0，表示没有更多的statement
		// 没有了更多的statement了，就退出
		if newlineCount == 0 {
			moreStatement = false
		}
		if !moreStatement {
			break
		}
		// 注册解析的结果（就是拿到解析结果里面的节点）
		statement = res.TryRegister(p.Statement())
		if statement == nil && res.Error_ != nil && res.Error_.ErrorName == "done" { // 表示 statement 为空，节点为空的
			res.Error_ = nil
			p.Reverse(res.ToReverseCount) // 往回走
			moreStatement = false
			continue
		}
		// 将拿到的节点放到数组里面去
		statements = append(statements, statement)
	}
	// 返回的是一个list的节点
	n := nodes.NewListNode(
		&nodes.ListNode{
			ElementNodes: statements,
			BaseNode: nodes.BaseNode{
				PosStart: posStart,
				PosEnd:   p.CurrentTok.PosEnd,
			},
		},
	)
	// 成功，返回节点
	return res.Success(n)
}

// statement 表达式
// statement		: KEYWORD:RETURN expr?
//						: KEYWORD:CONTINUE
//						: KEYWORD:BREAK
//						: expr
func (p *Parser) Statement() *ParseResult {
	// 初始化ParseResult
	res := NewParseResult()
	posStart := p.CurrentTok.PosStart.Copy()

	// 表示是关键字 RETURN
	var expr interface{}
	if p.CurrentTok.MatcheKeyword("RETURN") {
		res.RegisterAdvancement()
		p.Advance()

		// 拿到表达式的节点
		expr = res.TryRegister(p.Expr())
		if expr == nil { // 表达式为空，就往回走
			p.Reverse(res.ToReverseCount)
		}
		// 表达式不为空，就返回 return节点
		expr = nodes.NewReturnNode(
			&nodes.ReturnNode{
				NodeToReturn: expr,
				BaseNode: nodes.BaseNode{
					PosStart: posStart,
					PosEnd:   p.CurrentTok.PosStart.Copy(),
				},
			},
		)
	}

	// 表示是关键字 CONTINUE
	if p.CurrentTok.MatcheKeyword("CONTINUE") {
		res.RegisterAdvancement()
		p.Advance()

		// 表达式不为空，就返回 return节点
		expr = nodes.NewContinueNode(
			&nodes.ContinueNode{
				BaseNode: nodes.BaseNode{
					PosStart: posStart,
					PosEnd:   p.CurrentTok.PosStart.Copy(),
				},
			},
		)
	}

	// 表示是关键字 BREAK
	if p.CurrentTok.MatcheKeyword("BREAK") {
		res.RegisterAdvancement()
		p.Advance()

		// 表达式不为空，就返回 return节点
		expr = nodes.NewBreakNode(
			&nodes.BreakNode{
				BaseNode: nodes.BaseNode{
					PosStart: posStart,
					PosEnd:   p.CurrentTok.PosStart.Copy(),
				},
			},
		)
	}

	// 注册expr表达式
	expr = res.Register(p.Expr())
	// 报错了，就返回失败
	if res.Error_ != nil {
		return res
	}
	// 将成功解析出来的节点进行返回，
	return res.Success(expr)
}

// 解析表达式 Expr
// expr        : KEYWORD:VAR IDENTIFIER EQ expr
//            : comp-expr ((KEYWORD:AND|KEYWORD:OR) comp-expr)*
func (p *Parser) Expr() *ParseResult {
	res := NewParseResult()

	// 匹配关键字 VAR 解析变量表达式
	if p.CurrentTok.MatcheKeyword("VAR") {
		res.RegisterAdvancement() // 注册器前进1
		p.Advance()               // 解析器前进1

		// 不为标识符，就报错
		if p.CurrentTok.Type_ != constants.TT_IDENTIFIER {
			return res.Failure(interpreter.NewError(p.CurrentTok.PosStart, p.CurrentTok.PosEnd, "语法错误", "关键字var后面应该跟标识符"))
		}

		// 变量名称
		varName := p.CurrentTok
		res.RegisterAdvancement() // 注册前进1
		p.Advance()               // 解析器前进1

		// 当前token不是 =
		if p.CurrentTok.Type_ != constants.TT_EQ {
			return res.Failure(interpreter.NewError(p.CurrentTok.PosStart, p.CurrentTok.PosEnd, "语法错误", "标识符后面应该跟等号"))
		}

		res.RegisterAdvancement() // 注册前进1
		p.Advance()               // 解析器前进1

		// 注册下一个表达式
		expr := res.Register(p.Expr())
		if res.Error_ != nil {
			return res
		}
		// 成功返回 变量分配的节点，把变量名称以及变量的表达式分配进去
		return res.Success(nodes.NewVarAssignNode(
			&nodes.VarAssignNode{
				VarNameTok:   varName,
				VarValueNode: expr, // 转化为Token类型，因为expr为任意类型，一般为node类型
			},
		))
	}

	// 变量左边搞定了之后，开始注册比较 表达式
	temp := []interface{}{
		map[string]string{
			constants.TT_KEYWORD: constants.KEYWORDS["AND"].(string),
		},
		map[string]string{
			constants.TT_KEYWORD: constants.KEYWORDS["OR"].(string),
		},
	}
	// 注册相应的 表达式 的节点
	node := res.Register(p.BinOp(p.CompExpr, temp, nil))
	if res.Error_ != nil {
		return res
	}
	return res.Success(node)
}

// 创建比较表达式，有两种方式
// expr        : KEYWORD:VAR IDENTIFIER EQ expr
//             : comp-expr ((KEYWORD:AND|KEYWORD:OR) comp-expr)*
func (p *Parser) CompExpr() *ParseResult {
	res := NewParseResult()

	// 首先有一个 NOT 关键字
	if p.CurrentTok.MatcheKeyword("NOT") {
		// 当前的token切换为opToken
		opTok := p.CurrentTok
		// 解析器，解析结果，向前走
		res.RegisterAdvancement()
		p.Advance()

		// 然后将 后面的创建comp-expr表达式
		node := res.Register(p.CompExpr())

		if res.Error_ != nil || node == nil {
			return res
		}
		// 如果走到了这里就表示已经获取到了当前的表达式的所有节点了，
		// 因此就把这个节点与当前的token封装成为UnaryOpNode（一元表达式节点）
		// 返回出去
		return res.Success(nodes.NewUnaryOpNode(
			&nodes.UnaryOpNode{
				OpTok: opTok,
				Node:  node, // 是一个节点
			},
		))
	}

	// 其次有可能是第二种，arith-expr ((EE|LT|GT|LTE|GTE) arith-expr)*,这个是一个BinOp表达式（）
	temp := []interface{}{
		constants.TT_EE,
		constants.TT_NE,
		constants.TT_LT,
		constants.TT_GT,
		constants.TT_LTE,
		constants.TT_GTE,
	}
	node := res.Register(p.BinOp(p.ArithExpr, temp, nil))
	if res.Error_ != nil {
		return res
	}

	// 走到了这里表示成功解析了第二种表达式
	return res.Success(node)
}

// 创建 BinOp 表达式 是这种格式的 comp-expr ((KEYWORD:AND|KEYWORD:OR) comp-expr)* 对应为 funcA (ops funcB)*
func (p *Parser) BinOp(funcA func() *ParseResult, ops []interface{}, funcB func() *ParseResult) *ParseResult {
	// funcB 为空时，就把funcB作为funcA一样
	if funcB == nil {
		funcB = funcA
	}

	res := NewParseResult()
	left := res.Register(funcA())
	if res.Error_ != nil {
		return res
	}

	// 条件1，字符串是否在 数组中
	// 条件2，map是否在数组中
	for utils.IsContain(ops, p.CurrentTok.Type_) || utils.IsContainMap(ops, p.CurrentTok.Type_, p.CurrentTok.Value) { // 在数组中，表示当前的token就是传进来的需求的token类型，
		opTok := p.CurrentTok
		res.RegisterAdvancement()
		p.Advance()

		right := res.Register(funcB())
		if res.Error_ != nil || right == nil {
			return res.Failure(interpreter.NewError(p.CurrentTok.PosStart, p.CurrentTok.PosEnd, "语法错误", "缺少被操作的操作数"))
		}

		left = nodes.NewBinOpNode(
			&nodes.BinOpNode{
				LeftNode:  left,
				OpTok:     opTok,
				RightNode: right,
			})
	}

	return res.Success(left)
}

// 创建 arith-expr 表达式
// arith-expr  :	term ((PLUS|MINUS) term)*
func (p *Parser) ArithExpr() *ParseResult {
	temp := []interface{}{
		constants.TT_PLUS,
		constants.TT_MINUS,
	}
	arithExpr := p.BinOp(p.Term, temp, nil)
	return arithExpr
}

// 创建 term 表达式
// term        : factor ((MUL|DIV) factor)*
func (p *Parser) Term() *ParseResult {
	temp := []interface{}{
		constants.TT_MUL,
		constants.TT_DIV,
		constants.TT_YU,
	}
	term := p.BinOp(p.Factor, temp, nil) // 为了方便测试
	return term
}

// 创建 factor 表达式
// factor      : (PLUS|MINUS) factor
//             : power
func (p *Parser) Factor() *ParseResult {
	// 创建一个新的解析结果对象，当前的token记录下来
	res := NewParseResult()
	tok := p.CurrentTok

	// 判断当前的token的类型为加还是减,factor      : (PLUS|MINUS) factor
	if tok.Type_ == constants.TT_PLUS || tok.Type_ == constants.TT_MINUS {
		// 匹配到了，就解析结果往前走一，当前的解析器往前走一
		res.RegisterAdvancement()
		p.Advance()

		// 注册当前的factor
		factor := res.Register(p.Factor())
		if res.Error_ != nil || factor == nil {
			return res
		}
		// 走到这里表示成功了，就将当前的PLUS|MINUS与factor组合成相应的表达式节点，返回出去
		return res.Success(
			nodes.NewUnaryOpNode(
				&nodes.UnaryOpNode{
					OpTok: tok,
					Node:  factor,
				},
			))
	}

	// 走到了这里表示的是第二种情况 : power
	factor := p.Power()
	return factor
}

// 创建 power 表达式 power       : call (POW factor)*
func (p *Parser) Power() *ParseResult {
	temp := []interface{}{
		constants.TT_POW,
	}
	return p.BinOp(p.Call, temp, p.Factor)
}

// 创建 call 表达式 call        : atom (LPAREN (expr (COMMA expr)*)? RPAREN)?
func (p *Parser) Call() *ParseResult {
	res := NewParseResult()
	// 创建atom的表达式
	atom := res.Register(p.Atom())
	if res.Error_ != nil {
		return res
	}
	// 走到这一步表示已经创建atom表达式成功了，后面就检测 关键字 (LPAREN
	if p.CurrentTok.Type_ == constants.TT_LPAREN {
		res.RegisterAdvancement()
		p.Advance()
		var argNodes []interface{}
		// 创建 表达式 (expr,因为是？,表示是可以0-1个
		if p.CurrentTok.Type_ == constants.TT_RPAREN {
			res.RegisterAdvancement()
			p.Advance()
		} else {
			// 表示进了 (expr ，
			node := res.Register(p.Expr())
			argNodes = append(argNodes, node)
			// 表示有错误
			if res.Error_ != nil {
				return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个“)”括号"))
			}

			// 为 COMMA 关键字
			for p.CurrentTok.Type_ == constants.TT_COMMA {
				res.RegisterAdvancement()
				p.Advance()

				argNodes = append(argNodes, res.Register(p.Expr()))
				if res.Error_ != nil {
					return res
				}
			}

			// 走到这里表示的是已经走到了最后一步了，其他的都解析完成了，只有最后一个  RPAREN)
			if p.CurrentTok.Type_ != constants.TT_RPAREN {
				// 最后少了一个括号，语法错误
				return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个“)”括号"))
			}

			// 走到这里表示已经完成了解析了
			res.RegisterAdvancement()
			p.Advance()
		}
		// 走到这里表示解析完成，将token打包成Call节点
		return res.Success(nodes.NewCallNode(
			&nodes.CallNode{
				NodeToCall: atom,
				ArgNodes:   argNodes,
			},
		))

	}
	// 走到这里表示已经成功解析出了atom,
	return res.Success(atom)
}

// 创建 atom 表达式
// atom        : INT|FLOAT|STRING|IDENTIFIER
//            : LPAREN expr RPAREN
//            : list-expr
//            : if-expr
//            : for-expr
//            : while-expr
//            : func-def
func (p *Parser) Atom() *ParseResult {
	res := NewParseResult()
	tok := p.CurrentTok

	// 为整形或者浮点型，表示为数字
	if tok.Type_ == constants.TT_INT || tok.Type_ == constants.TT_FLOAT {
		res.RegisterAdvancement()
		p.Advance()
		return res.Success(nodes.NewNumberNode(
			&nodes.NumberNode{
				Tok: tok,
			}))
	} else if tok.Type_ == constants.TT_STRING { // 为字符串
		res.RegisterAdvancement()
		p.Advance()
		return res.Success(nodes.NewStringNode(
			&nodes.StringNode{
				Tok: tok,
			}))
	} else if tok.Type_ == constants.TT_IDENTIFIER { // 为标识符
		res.RegisterAdvancement()
		p.Advance()
		return res.Success(nodes.NewVarAccessNode(
			&nodes.VarAccessNode{
				VarNameTok: tok,
			}))
	} else if tok.Type_ == constants.TT_LPAREN { // 为左边的圆括号
		res.RegisterAdvancement()
		p.Advance()
		// 注册表达式expr
		expr := res.Register(p.Expr())
		if res.Error_ != nil {
			return res
		}
		// 当类型不为右边括号时，语法错误
		if p.CurrentTok.Type_ != constants.TT_RPAREN {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个“)”括号"))
		}

		// 走到这里表示第二种情况解析成功了
		res.RegisterAdvancement()
		p.Advance()
		return res.Success(expr)
	} else if tok.Type_ == constants.TT_LSQUARE { // 表示方括号，
		listExpr := res.Register(p.ListExpr()) // 就开始创建 list-expr 表达式
		if res.Error_ != nil {
			return res
		}
		return res.Success(listExpr)
	} else if tok.MatcheKeyword("IF") { // token为关键字，而且关键字为IF时
		ifExpr := res.Register(p.IfExpr()) // 就开始创建 if-expr 表达式
		if res.Error_ != nil {
			return res
		}
		return res.Success(ifExpr)
	} else if tok.MatcheKeyword("FOR") { // token为关键字，而且关键字为 FOR 时
		forExpr := res.Register(p.ForExpr()) // 就开始创建 if-expr 表达式
		if res.Error_ != nil {
			return res
		}
		return res.Success(forExpr)
	} else if tok.MatcheKeyword("WHILE") { // token为关键字，而且关键字为 WHILE 时
		whileExpr := res.Register(p.WhileExpr()) // 就开始创建 while-expr 表达式
		if res.Error_ != nil {
			return res
		}
		return res.Success(whileExpr)
	} else if tok.MatcheKeyword("FUN") { // token为关键字，而且关键字为 FUN 时
		funExpr := res.Register(p.FuncExpr()) // 就开始创建 fun-expr 表达式
		if res.Error_ != nil {
			return res
		}
		return res.Success(funExpr)
	}
	// 走到这里表示所有的可能性的 表达式已经解析完成了，按道理是无法到达这里的，所以判定存在着语法错误，
	return res.Failure(interpreter.NewFinishedError(p.CurrentTok, ""))
}

// 创建 list-expr 表达式 list-expr   : LSQUARE (expr (COMMA expr)*)? RSQUARE
func (p *Parser) ListExpr() *ParseResult {
	res := NewParseResult()
	// 存储所有的节点
	var elementsNodes []interface{}

	posStart := p.CurrentTok.PosStart.Copy()

	// 表示左边的不是方括号，就表示语法错误
	if p.CurrentTok.Type_ != constants.TT_LSQUARE {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个“[”括号"))
	}

	res.RegisterAdvancement()
	p.Advance()

	// 当前的token为右边的方括号
	if p.CurrentTok.Type_ == constants.TT_RSQUARE {
		res.RegisterAdvancement()
		p.Advance()
	} else { // 不是右边的方括号，就是内部表达式
		// 利用当前的解析器制作成表达式，然后添加进数组中
		elementsNodes = append(elementsNodes, res.Register(p.Expr()))
		if res.Error_ != nil { // 到了这里表示语法报错了，
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个“]”括号"))
		}

		// 解析 (COMMA expr)*的表达式
		for p.CurrentTok.Type_ == constants.TT_COMMA {
			res.RegisterAdvancement()
			p.Advance()

			elementsNodes = append(elementsNodes, res.Register(p.Expr()))
			if res.Error_ != nil {
				return res
			}
		}

		// 走到这里表示 最后一个不为右边的方括号，就必然是语法错误
		if p.CurrentTok.Type_ != constants.TT_RSQUARE {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个“]”括号"))
		}

		res.RegisterAdvancement()
		p.Advance()
	}
	// 走到这里表示所有的都解析完成了，就返回出去 ListNode节点
	return res.Success(nodes.NewListNode(
		&nodes.ListNode{
			ElementNodes: elementsNodes,
			BaseNode: nodes.BaseNode{
				PosStart: posStart,
				PosEnd:   p.CurrentTok.PosEnd.Copy(),
			},
		}))
}

// 创建一个 if-expr 表达式
// if-expr     : KEYWORD:IF expr KEYWORD:THEN
//              (statement if-expr-b|if-expr-c?)
//            | (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)
func (p *Parser) IfExpr() *ParseResult {
	res := NewParseResult()
	allCases, err := res.Register(p.IfExprAndBCommon("IF")).(*nodes.AllCases)
	if !err {
		res.Error_ = interpreter.NewIllegalError(p.CurrentTok, "if后面缺少条件")
		return res
	}
	if res.Error_ != nil {
		return res
	}
	cases := allCases.Cases
	elseCase := allCases.ElseCase
	return res.Success(nodes.NewIfNode(
		&nodes.IfNode{
			Cases:    cases,
			ElseCase: elseCase,
		},
	))
}

// 创建一个 if_expr_b 表达式
// if-expr-b   : KEYWORD:ELIF expr KEYWORD:THEN
//              (statement if-expr-b|if-expr-c?)
//            | (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)
func (p *Parser) IfExprB() *ParseResult {
	return p.IfExprAndBCommon("ELIF")
}

// 创建一个 if_expr_c 表达式
//if-expr-c   : KEYWORD:ELSE
//              statement
//            | (NEWLINE statements KEYWORD:END)
func (p *Parser) IfExprC() *ParseResult {
	res := NewParseResult()
	var elseCase *nodes.ElseCase

	// 关键字为 ELSE 时
	if p.CurrentTok.MatcheKeyword("ELSE") {
		res.RegisterAdvancement()
		p.Advance()

		if p.CurrentTok.Type_ == constants.TT_NEWLINE {
			res.RegisterAdvancement()
			p.Advance()

			// 解析到了statements
			statements := res.Register(p.Statements())
			if res.Error_ != nil {
				return res
			}
			// elseCase 就变成了表达式
			elseCase = &nodes.ElseCase{
				Expr:             statements,
				ShouldReturnNull: true,
			}
			// 解析到end关键字了
			if p.CurrentTok.MatcheKeyword("END") {
				res.RegisterAdvancement()
				p.Advance()
			} else {
				// 没有匹配到end关键字，提示语法错误
				return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "这里少了个 end 结束符"))
			}
		} else {
			expr := res.Register(p.Statement())
			if res.Error_ != nil {
				return res
			}
			elseCase = &nodes.ElseCase{
				Expr:             expr,
				ShouldReturnNull: false,
			}
		}
	}
	return res.Success(elseCase)
}

// 创建一个 if-expr-b|if-expr-c 表达式，因为在比较多的地方都用到了这个，所以把他们合并
// if-expr-b   : KEYWORD:ELIF expr KEYWORD:THEN
//              (statement if-expr-b|if-expr-c?)
//            | (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)
func (p *Parser) IfExprBOrC() *ParseResult {
	res := NewParseResult()
	var cases []nodes.Case
	var elseCase *nodes.ElseCase
	var allCases *nodes.AllCases

	if p.CurrentTok.MatcheKeyword("ELIF") {
		allCases = res.Register(p.IfExprB()).(*nodes.AllCases)
		if res.Error_ != nil {
			return res
		}
		cases = allCases.Cases
		elseCase = allCases.ElseCase
	} else {
		elseCase = res.Register(p.IfExprC()).(*nodes.ElseCase)
		if res.Error_ != nil {
			return res
		}
	}
	// 所有的case返回
	return res.Success(&nodes.AllCases{
		Cases:    cases,
		ElseCase: elseCase,
	})
}

// 创建一个 IfExpr 与 IfExprB 公共的表达式函数
func (p *Parser) IfExprAndBCommon(caseKeyword string) *ParseResult {
	res := NewParseResult()

	var cases []nodes.Case
	var elseCase *nodes.ElseCase
	var allCases *nodes.AllCases

	// 关键字存在，比如为IF关键字或者ELIF关键字，关键字不存在就表示语法错误
	if !p.CurrentTok.MatcheKeyword(caseKeyword) {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该为if 或者 为 elseif"))
	}

	res.RegisterAdvancement()
	p.Advance()

	// 开始创建表达式 这个为条件表达式
	condition := res.Register(p.Expr())
	if res.Error_ != nil {
		return res
	}

	// 关键字不为THEN的关键字，报语法错误
	if !p.CurrentTok.MatcheKeyword("THEN") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前缺少一个关键字 then"))
	}

	// 到了这里表示语法正确
	res.RegisterAdvancement()
	p.Advance()

	// 表示解析到了新行
	if p.CurrentTok.Type_ == constants.TT_NEWLINE {
		res.RegisterAdvancement()
		p.Advance()

		statements := res.Register(p.Statements())
		if res.Error_ != nil {
			return res
		}
		// 添加进cases中
		cases = append(cases, nodes.Case{
			Condition:        condition,
			Expr:             statements,
			ShouldReturnNull: true,
		})

		// 走到这里表示前面的都解析完了，开始解析是否有end关键字了
		if p.CurrentTok.MatcheKeyword("END") {
			res.RegisterAdvancement()
			p.Advance()
		} else { // 不是end关键字，就是 if-expr-b/if-expr-c
			allCases = res.Register(p.IfExprBOrC()).(*nodes.AllCases)
			if res.Error_ != nil {
				return res
			}
			// 将获取到的 elseCases 变成最新的
			elseCase = allCases.ElseCase
			// 把获取到的cases添加放到cases数组里面去
			cases = append(cases, allCases.Cases...)
		}
	} else { // 表示为 (statement if-expr-b|if-expr-c?) 这个表达式
		expr := res.Register(p.Statement())
		if res.Error_ != nil {
			return res
		}
		cases = append(cases, nodes.Case{
			Condition:        condition,
			Expr:             expr,
			ShouldReturnNull: false,
		})
		// 解析 if-expr-b|if-expr-c?这个表达式
		allCases := res.Register(p.IfExprBOrC()).(*nodes.AllCases)
		if res.Error_ != nil {
			return res
		}
		// 将获取到的 elseCases 变成最新的
		elseCase = allCases.ElseCase
		// 把获取到的cases添加放到cases数组里面去
		cases = append(cases, allCases.Cases...)
	}

	// 走到这里表示的意思为成功解析了
	return res.Success(&nodes.AllCases{
		Cases:    cases,
		ElseCase: elseCase,
	})
}

// 创建一个 for-expr 表达式
// for-expr    : KEYWORD:FOR IDENTIFIER EQ expr KEYWORD:TO expr
//              (KEYWORD:STEP expr)? KEYWORD:THEN
//              statement
//            | (NEWLINE statements KEYWORD:END)
// for a = 1 to 23 step 2 then return "asdas" end
// 或者为
// for a = 1 to 23 step 2 then
//  1+2
//  2+3
// end
func (p *Parser) ForExpr() *ParseResult {
	res := NewParseResult()

	// 检测到了 For 关键字
	if !p.CurrentTok.MatcheKeyword("FOR") {
		return res.Failure(nil)
	}

	res.RegisterAdvancement()
	p.Advance()

	// 关键字为标识符的话就往下走，没有这个不是标识符 就是表明是语法错了
	if p.CurrentTok.Type_ != constants.TT_IDENTIFIER {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是标识符（变量之类的）"))
	}
	// 1.变量名称（标识符名称）
	varName := p.CurrentTok
	res.RegisterAdvancement()
	p.Advance()

	// 不是 等于 也语法错误
	if p.CurrentTok.Type_ != constants.TT_EQ {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“=”等号"))
	}

	res.RegisterAdvancement()
	p.Advance()

	// 2.开始的值
	startValue := res.Register(p.Expr())
	if res.Error_ != nil {
		return res
	}

	// 检测到了 To 关键字,没有监测到就提示报错，语法错误
	if !p.CurrentTok.MatcheKeyword("TO") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“to”关键字"))
	}

	res.RegisterAdvancement()
	p.Advance()

	// 3.结束的值
	endValue := res.Register(p.Expr())
	if res.Error_ != nil {
		return res
	}

	// 检测到了 Step 关键字,没有监测到就提示报错，语法错误
	var stepValue interface{}
	if p.CurrentTok.MatcheKeyword("STEP") {
		res.RegisterAdvancement()
		p.Advance()

		// 4.每一步的值
		stepValue = res.Register(p.Expr())
		if res.Error_ != nil {
			return res
		}
	} else {
		stepValue = nil
	}

	// 没有监测到Then关键字就提示为语法错误
	if !p.CurrentTok.MatcheKeyword("THEN") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“then”关键字"))
	}

	res.RegisterAdvancement()
	p.Advance()

	// 表示为新行时
	if p.CurrentTok.Type_ == constants.TT_NEWLINE {
		res.RegisterAdvancement()
		p.Advance()

		body := res.Register(p.Statements())
		if res.Error_ != nil {
			return res
		}

		// 最后一个关键字不是结束 END ，就表明语法错了
		if !p.CurrentTok.MatcheKeyword("END") {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“end”关键字"))
		}

		res.RegisterAdvancement()
		p.Advance()

		// 走到了这里表明语法正确，已经解析完成了
		return res.Success(nodes.NewForNode(
			&nodes.ForNode{
				VarNameToken:     varName,
				StartValueNode:   startValue,
				EndValueNode:     endValue,
				StepValueNode:    stepValue,
				BodyNode:         body,
				ShouldReturnNull: true,
			}))
	}

	// 解析到了这里表明是第二种解析情况 statement ,这种情况下 是一句下写的语法，这个最后没有End关键字，
	body := res.Register(p.Statement())
	if res.Error_ != nil {
		return res
	}
	return res.Success(nodes.NewForNode(
		&nodes.ForNode{
			VarNameToken:     varName,
			StartValueNode:   startValue,
			EndValueNode:     endValue,
			StepValueNode:    stepValue,
			BodyNode:         body,
			ShouldReturnNull: false,
		}))
}

// 解析 while 的表达式
// while-expr  : KEYWORD:WHILE expr KEYWORD:THEN
//              statement
//            | (NEWLINE statements KEYWORD:END)
func (p *Parser) WhileExpr() *ParseResult {
	res := NewParseResult()

	// 没有while 的关键字就直接报错
	if !p.CurrentTok.MatcheKeyword("WHILE") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "该位置应该是关键字while"))
	}
	res.RegisterAdvancement()
	p.Advance()

	condition := res.Register(p.Expr())

	// 没有陪陪到 THEN 关键字，语法错误
	if !p.CurrentTok.MatcheKeyword("THEN") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "该位置应该是关键字then"))
	}

	res.RegisterAdvancement()
	p.Advance()
	// 为新行，解析下面的 (NEWLINE statements KEYWORD:END)
	if p.CurrentTok.Type_ == constants.TT_NEWLINE {

		body := res.Register(p.Statements())

		// 没有陪陪到 END 关键字，语法错误
		if !p.CurrentTok.MatcheKeyword("END") {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“end”关键字"))
		}
		res.RegisterAdvancement()
		p.Advance()

		// 走到了这里，表明是语法正确了
		return res.Success(nodes.NewWhileNode(
			&nodes.WhileNode{
				ConditionNode:    condition,
				BodyNode:         body,
				ShouldReturnNull: true,
			}))
	}
	// 解析完了上面的，就开始第二种情况,为单行语法
	body := res.Register(p.Statement())
	return res.Success(nodes.NewWhileNode(
		&nodes.WhileNode{
			ConditionNode:    condition,
			BodyNode:         body,
			ShouldReturnNull: false,
		}))
}

// 解析函数表达式
// func-def    : KEYWORD:FUN IDENTIFIER?
//              LPAREN (IDENTIFIER (COMMA IDENTIFIER)*)? RPAREN
//              (ARROW expr)
//            | (NEWLINE statements KEYWORD:END)
// fun as (d Vas,b Vss )
// 	 var a = 1+1
// 	 var b = 1+1
// end
func (p *Parser) FuncExpr() *ParseResult {
	res := NewParseResult()

	// 关键字不匹配，语法错误
	if !p.CurrentTok.MatcheKeyword("FUN") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“func”关键字"))
	}

	res.RegisterAdvancement()
	p.Advance()

	// 1.函数名字（标识符名字）
	var varNameTok *token.Token
	if p.CurrentTok.Type_ == constants.TT_IDENTIFIER {

		varNameTok = p.CurrentTok
		res.RegisterAdvancement()
		p.Advance()

		// 当前的token不是左括号类型，就表明语法错误
		if p.CurrentTok.Type_ != constants.TT_LPAREN {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“(”括号"))
		}
	} else { // 当前的不是标识符，而且也没有响应的左边括号，就表明语法错误
		varNameTok = nil
		if p.CurrentTok.Type_ != constants.TT_LPAREN {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“(”括号"))
		}
	}
	res.RegisterAdvancement()
	p.Advance()

	// 2.参数名字
	var argNameToks []token.Token

	// 当前的为标识符
	if p.CurrentTok.Type_ == constants.TT_IDENTIFIER {
		argNameToks = append(argNameToks, *p.CurrentTok)
		res.RegisterAdvancement()
		p.Advance()

		for p.CurrentTok.Type_ == constants.TT_COMMA {
			res.RegisterAdvancement()
			p.Advance()

			// 不是标识符，语法错误
			if p.CurrentTok.Type_ != constants.TT_IDENTIFIER {
				return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是标识符（变量等之类的）"))
			}

			argNameToks = append(argNameToks, *p.CurrentTok)
			res.RegisterAdvancement()
			p.Advance()
		}

		// 语法解析到了右括号了,如果不是，就表明语法错误
		if p.CurrentTok.Type_ != constants.TT_RPAREN {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“)”括号"))
		}
	} else { // 表明不是标识符，就必须是右括号，不然就语法错了
		if p.CurrentTok.Type_ != constants.TT_RPAREN {
			return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“)”括号"))
		}
	}

	res.RegisterAdvancement()
	p.Advance()

	// token类型为箭头->,表明是一句函数，往下走一步，然后，获取到expr的token
	if p.CurrentTok.Type_ == constants.TT_ARROW {
		res.RegisterAdvancement()
		p.Advance()

		body := res.Register(p.Expr())
		if res.Error_ != nil {
			return res
		}

		return res.Success(nodes.NewFuncDefNode(
			&nodes.FuncDefNode{
				VarNameTok:       varNameTok,
				ArgNameToks:      argNameToks,
				BodyNode:         body,
				ShouldAutoReturn: true,
			}))
	}

	// token类型为newLine,表明函数为第二种,不为第二种就表明语法错了
	if p.CurrentTok.Type_ != constants.TT_NEWLINE {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是新的一行"))
	}
	res.RegisterAdvancement()
	p.Advance()

	// 得到statements 的
	body := res.Register(p.Statements())
	if res.Error_ != nil {
		return res
	}

	// 表明语法错误，最后一个关键字不是 END
	if !p.CurrentTok.MatcheKeyword("END") {
		return res.Failure(interpreter.NewIllegalError(p.CurrentTok, "当前应该是“end”关键字"))
	}

	// 走到了这里表明语法已经解析完成，返回解析结果
	res.RegisterAdvancement()
	p.Advance()
	return res.Success(nodes.NewFuncDefNode(
		&nodes.FuncDefNode{
			VarNameTok:       varNameTok,
			ArgNameToks:      argNameToks,
			BodyNode:         body,
			ShouldAutoReturn: false,
		}))

}
